package com.essg.sdc.study;

import com.essg.sdc.base.BaseAlgo;

/**
 * <H1>新人社員向けアルゴリズム(Java)</H1>
 *<H2>アルゴリズム（大中小計）</H2><br>
 *<ol>
 *	<li>社員情報(EmpData)を自動生成（Superクラスで実施）
 *	<li>社員情報の一覧表示を行う。
 *	<li>部署コード・課コードでコントロールブレークを行いながら課合計、部署合計を表示する。
 *</ol>
 *
 * @author ess0034
 */
public class ControlBreakSumUp extends BaseAlgo {

	/**
	 * コントロールブレーク　セーブキー
	 */
	private EmpData mSvEmp;
	/**
	 * コントロールブレーク　トランキー
	 */
	private EmpData mTrEmp;
	/**
	 * 部署印刷フラグ
	 */
	private boolean mDivHeader;
	/**
	 * 課印刷フラグ
	 */
	private boolean mSecHeader;

	/**
	 * 総給与合計
	 */
	private double mTtlSum;
	/**
	 * 部署給与合計
	 */
	private double mDivSum;
	/**
	 * 課給与合計
	 */
	private double mSecSum;

	/**
	 * <H2>大中小計　コンストラクタ</H2>
	 * <ol>
	 * 	<li>Superクラスを実行し社員情報を作成する。
	 * </ol>
	 */
	public ControlBreakSumUp() {
		super(ALGO_TYPE.CONTROLBREAKSUMUP);
	}

	/**
	 * <H2>大中小計</H2><P>
	 * <ol>
	 *	<li>部署コード、課コード毎の給与合計を加算しながら、部署、課がコントロールブレークするタイミングで表示する。
	 *	<li>社員情報を一覧表示する。
	 * </ol>
	 */
	@Override
	public void ListAlgo() {

		mSvEmp = new EmpData();
		mSvEmp.setDivcd(String.valueOf(0x00));
		mTrEmp = nextEmp();
		mDivHeader = false;
		mSecHeader = false;
		mTtlSum = 0;
		mDivSum = 0;
		mSecSum = 0;

		while(!mTrEmp.getDivcd().equals(HIGH_VALUE)){
			while(mSvEmp.getDivcd().equals(mTrEmp.getDivcd())){
				while(mSvEmp.getDivcd().equals(mTrEmp.getDivcd()) && mSvEmp.getSeccd().equals(mTrEmp.getSeccd())){
					printDetail();
					mSecSum += mTrEmp.getPay();
					mTrEmp = nextEmp();
				}
				printSection();
			}
			printDivision();
		}

	}

	/**
	 * <H2>部署情報表示</H2><P>
	 * 部署コードがブレークした場合に実行される。<br>
	 * 部署情報および課情報の計を表示する。
	 * 初期段階での表示を制御するためLow-Value(0x00)を使用して制御を行う。
	 * EOFの段階で総合計を表示する。
	 */
	private void printDivision(){

		String _detail;
		if(!mSvEmp.getDivcd().equals(String.valueOf(0x00))){
			_detail = "    " + mSvEmp.getSeccd() + String.format("                          \\%1$0,3d", (int)mSecSum);
			System.out.println(_detail);
			_detail = mSvEmp.getDivcd() + String.format("                             \\%1$0,3d", (int)mDivSum);
			System.out.println(_detail);
			mTtlSum += mDivSum;
		}

		mSvEmp.setSeccd(mTrEmp.getSeccd());
		mSvEmp.setDivcd(mTrEmp.getDivcd());

		if(mTrEmp.getDivcd().equals(HIGH_VALUE)){
			_detail = String.format("Total                          \\%1$0,3d", (int)mTtlSum);
			System.out.println(_detail);
			return;
		}

		System.out.println("Div Sec Esscd   Name            Pay");
		System.out.print(mTrEmp.getDivcd() + " " + mTrEmp.getSeccd());
		mDivHeader = true;
		mSecHeader = true;
		mDivSum = 0;
		mSecSum = 0;
	}

	/**
	 * <H2>課情報表示</H2><P>
	 * 課コードのみがブレークした場合のみ、課計を表示する。
	 */
	private void printSection(){

		mDivSum += mSecSum;
		if(mTrEmp.getSeccd().equals(HIGH_VALUE)) return;
		if(!mSvEmp.getDivcd().equals(mTrEmp.getDivcd())) return;
		if(mDivHeader) return;

		String _detail;

		_detail = "    " + mSvEmp.getSeccd() + String.format("                          \\%1$0,3d", (int)mSecSum);
		System.out.println(_detail);
		mSvEmp.setSeccd(mTrEmp.getSeccd());
		_detail = "    " + mTrEmp.getSeccd();
		System.out.print(_detail);
		mSecHeader = true;
		mSecSum = 0;

	}

	/**
	 * <H2>社員情報表示</H2><P>
	 * 社員情報を表示する。<P>
	 * 部署・課が表示された場合は、続けて表示<br>
	 * 上記以外の場合は、空白で位置合わせを行い表示する。
	 *
	 */
	private void printDetail(){

		String _detail;

		if(mSecHeader){
			_detail = "  " + mTrEmp.getEsscd() + " " + mTrEmp.getName() + String.format(" \\%1$0,3d", mTrEmp.getPay());
		}else{
			_detail = "        " + mTrEmp.getEsscd() + " " + mTrEmp.getName() + String.format(" \\%1$0,3d", mTrEmp.getPay());
		}
		System.out.println(_detail);
		mDivHeader = false;
		mSecHeader = false;
	}

	/**
	 * 大中小計の実行メイン
	 * @param args 実行パラメタ（今回は未使用）
	 * ControlBreakをインスタンス化し、ListAlgo(大中小計)を実行
	 */
	public static void main(String[] args) {

		ControlBreakSumUp _obj = new ControlBreakSumUp();
		_obj.ListAlgo();

	}

}
